/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include "keyboardmain.h"

KeyboardMain::KeyboardMain() : mFirstLoad(true)
{
    pluginName = tr("Keyboard");
    pluginType = DEVICES;
}

KeyboardMain::~KeyboardMain()
{
}

QString KeyboardMain::plugini18nName()
{
    return pluginName;
}

int KeyboardMain::pluginTypes() {
    return pluginType;
}

QWidget *KeyboardMain::pluginUi()
{
    if (mFirstLoad) {
        mFirstLoad = false;
        pluginWidget = new QWidget;
        pluginWidget->setAttribute(Qt::WA_DeleteOnClose);
        initUI(pluginWidget);
        initConnection();
    }
    return pluginWidget;
}

const QString KeyboardMain::name() const
{
    return QStringLiteral("Keyboard");
}

bool KeyboardMain::isShowOnHomePage() const
{
    return true;
}

QIcon KeyboardMain::icon() const
{
    return QIcon::fromTheme("input-keyboard-symbolic");
}

bool KeyboardMain::isEnable() const
{
    return !Common::isWayland();
}

void KeyboardMain::initUI(QWidget *widget)
{
    mVlayout = new QVBoxLayout(widget);
    mVlayout->setContentsMargins(0, 0, 0, 0);;

    mKeyboardFrame = new SettingGroup(this);

    mKeyboardSetTitleLabel = new TitleLabel(this);
    mKeyboardSetTitleLabel->setText(tr("Key board settings"));
    mKeyboardSetTitleLabel->setContentsMargins(16, 0, 0, 0);

    setKeyRepeatFrame();
    setDelayFrame();
    setSpeedFrame();
    setInputTestFrame();
    setKeyTipsFrame();

    /* Input method */
    mInputMethodSetBtn = new QPushButton(this);
    //~ contents_path /Keyboard/Input settings
    mInputMethodSetBtn->setText(tr("Input settings"));
    mInputMethodSetBtn->setObjectName("Input settings");
    mInputMethodSetBtn->setFixedSize(QSize(160, 36));

    /* add widget */
    mKeyboardFrame->insertWidget(0, mKeyRepeatFrame);
    mKeyboardFrame->insertWidget(1, mDelayFrame);
    mKeyboardFrame->insertWidget(2, mSpeedFrame);
    mKeyboardFrame->insertWidget(3, mInputTestFrame);
    mKeyboardFrame->insertWidget(4, mKeyTipsFrame);

    mVlayout->addWidget(mKeyboardSetTitleLabel);
    mVlayout->setSpacing(8);
    mVlayout->addWidget(mKeyboardFrame);
    mVlayout->addWidget(mInputMethodSetBtn);
    mVlayout->addStretch();
}

void KeyboardMain::setKeyRepeatFrame()
{
    /* Key Repeat */
    //~ contents_path /Keyboard/Key repeat
    mKeyRepeatFrame = new SwitchWidget(tr("Key repeat"), this, UkccFrame::None);
    mKeyRepeatFrame->setObjectName("Key repeat");
}

void KeyboardMain::setDelayFrame()
{
    /* delay */
    //~ contents_path /Keyboard/Delay
    mDelayFrame = new SliderWidget(tr("Delay"), false, this);
    mDelayFrame->setObjectName("Delay");
    mDelayFrame->setLeftText(tr("Short"));
    mDelayFrame->setRightText(tr("Long"));
    mDelayFrame->slider()->setMinimum(200);
    mDelayFrame->slider()->setMaximum(2100);
    mDelayFrame->slider()->setPageStep(20);
    mDelayFrame->slider()->setSingleStep(20);
    mDelayFrame->slider()->installEventFilter(this);
}

void KeyboardMain::setSpeedFrame()
{
    /* Speed */
    //~ contents_path /Keyboard/Speed
    mSpeedFrame = new SliderWidget(tr("Speed"), false, this);
    mSpeedFrame->setObjectName("Speed");
    mSpeedFrame->setLeftText(tr("Slow"));
    mSpeedFrame->setRightText(tr("Fast"));
    mSpeedFrame->slider()->setMinimum(10);
    mSpeedFrame->slider()->setMaximum(110);
    mSpeedFrame->slider()->setPageStep(1);
    mSpeedFrame->slider()->installEventFilter(this);
}

void KeyboardMain::setInputTestFrame()
{
    /* Input test */

    //~ contents_path /Keyboard/Input test
    mInputTestFrame = new LineEditWidget(tr("Input test"), this);

}

void KeyboardMain::setKeyTipsFrame()
{
    /* key tips */
    //~ contents_path /Keyboard/Key tips
    mKeyTipsFrame = new SwitchWidget(tr("Key tips"), this, UkccFrame::None);
    mKeyTipsFrame->setObjectName("Key tips");
}

void KeyboardMain::initConnection()
{
    // 初始化键盘通用设置GSettings
    QByteArray keyBoardId(kKeyboardSchamas);
    // 初始化键盘按键提示GSettings 控制面板自带 不再判断是否安装
    QByteArray keyBoardOsdId(kKeyboardOsdSchemas);
    if (QGSettings::isSchemaInstalled(keyBoardId)) {
        mKeyboardGsettings = new QGSettings(kKeyboardSchamas, QByteArray(), this);
        mKeyboardOsdGsetting = new QGSettings(keyBoardOsdId);

        initKeyboardStatus();

        //将界面设置改动的key值写入GSettings
        connect(mKeyRepeatFrame, &SwitchWidget::stateChanged, this, &KeyboardMain::keyRepeatSlot);

        connect(mDelayFrame, &SliderWidget::valueChanged, this, &KeyboardMain::keyDelaySlot);

        connect(mSpeedFrame, &SliderWidget::valueChanged, this, &KeyboardMain::keySpeedSlot);

        connect(mKeyTipsFrame, &SwitchWidget::stateChanged, this, &KeyboardMain::keyTipsSlot);

        connect(mInputMethodSetBtn, &QPushButton::clicked, this, &KeyboardMain::inputMethodSetSlot);

        gsettingConnectUi();
    }
}

void KeyboardMain::initKeyboardStatus()
{
    //设置按键重复状态
    mKeyRepeatFrame->setChecked(mKeyboardGsettings->get(kKeyRepeatKey).toBool());
    setKeyboardVisible(mKeyRepeatFrame->isChecked());

    //设置按键重复的延时
    mDelayFrame->setValue(mKeyboardGsettings->get(kDelayKey).toInt());

    //设置按键重复的速度
    mSpeedFrame->setValue(mKeyboardGsettings->get(kSpeedKey).toInt());

    //设置按键提示状态
    mKeyTipsFrame->blockSignals(true);
    mKeyTipsFrame->setChecked(mKeyboardOsdGsetting->get(kKeyTipsKey).toBool());
    mKeyTipsFrame->blockSignals(false);

}

void KeyboardMain::setKeyboardVisible(bool checked)
{
    mDelayFrame->setVisible(checked);
    mSpeedFrame->setVisible(checked);
    mInputTestFrame->setVisible(checked);
}

void KeyboardMain::gsettingConnectUi()
{
    //命令行 set key 值，界面设置做出相应的变化
    connect(mKeyboardGsettings, &QGSettings::changed, this, [=](const QString &key) {
       if(key == "repeat") {
           mKeyRepeatFrame->setChecked(mKeyboardGsettings->get(kKeyRepeatKey).toBool());
           setKeyboardVisible(mKeyRepeatFrame->isChecked());
       } else if(key == "delay") {
           mDelayFrame->setValue(mKeyboardGsettings->get(kDelayKey).toInt());
       } else if(key == "rate") {
           mSpeedFrame->setValue(mKeyboardGsettings->get(kSpeedKey).toInt());
       }
    });

    connect(mKeyboardOsdGsetting, &QGSettings::changed,this, [=](const QString &key) {
       if(key == "showLockTip") {
           mKeyTipsFrame->blockSignals(true);
           mKeyTipsFrame->setChecked(mKeyboardOsdGsetting->get(kKeyTipsKey).toBool());
           mKeyTipsFrame->blockSignals(false);
       }
    });
}

/* Slot */
void KeyboardMain::keyRepeatSlot(bool checked)
{
    setKeyboardVisible(checked);
    mKeyboardGsettings->set(kKeyRepeatKey, checked);
    Common::buriedSettings(name(), mKeyRepeatFrame->objectName(), QString("setting"), checked ? "true":"false");
}

void KeyboardMain::keyDelaySlot(int value)
{
    mKeyboardGsettings->set(kDelayKey, value);
}

void KeyboardMain::keySpeedSlot(int value)
{
    mKeyboardGsettings->set(kSpeedKey, value);
}

void KeyboardMain::keyTipsSlot(bool checked)
{
    mKeyboardOsdGsetting->set(kKeyTipsKey, checked);
    Common::buriedSettings(name(), mKeyTipsFrame->objectName(), QString("setting"), checked ? "true":"false");
}

void KeyboardMain::inputMethodSetSlot()
{
    Common::buriedSettings(name(), mInputMethodSetBtn->objectName(), QString("setting"));

    QProcess process;
    process.startDetached("fcitx5-config-qt");
}

bool KeyboardMain::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::FocusOut) {
        if (watched == mDelayFrame->slider()) {
            int value = mDelayFrame->value();
            Common::buriedSettings(name(), mDelayFrame->objectName(), QString("setting"), QString::number(value));
        } else if (watched == mSpeedFrame->slider()) {
            int value = mSpeedFrame->value();
            Common::buriedSettings(name(), mSpeedFrame->objectName(), QString("setting"), QString::number(value));
        }
    }
    return QObject::eventFilter(watched, event);
}

